package com.itany.nmms.service.impl;

import com.itany.nmms.constant.DictConstant;
import com.itany.nmms.constant.StatusConstant;
import com.itany.nmms.dao.DeptMapper;
import com.itany.nmms.dao.SequenceMapper;
import com.itany.nmms.entity.*;
import com.itany.nmms.exception.DeptExistException;
import com.itany.nmms.exception.DeptStatusErrorException;
import com.itany.nmms.exception.LoginDisabledException;
import com.itany.nmms.exception.RequestParameterErrorException;
import com.itany.nmms.service.DeptService;
import com.itany.nmms.util.ParameterUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Author:shixiaojun@itany.com
 * Date:2022/5/26 9:15
 * Version:1.0-SNAPSHOT
 * Description:
 */
@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public class DeptServiceImpl implements DeptService {

    @Autowired
    private SequenceMapper sequenceMapper;
    @Autowired
    private DeptMapper deptMapper;

    @Override
    public void addFatherDept(String name, String remark, Staff staff) throws RequestParameterErrorException, LoginDisabledException, DeptExistException {
        if(ParameterUtil.isNull(name) || ParameterUtil.isNull(remark)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        if(null == staff){
            throw new LoginDisabledException("登录失效,请重新登录");
        }
        // 部门名称不能重复
        DeptExample example = new DeptExample();
        example.or()
                .andDeptNameEqualTo(name);
        List<Dept> depts = deptMapper.selectByExample(example);
        if(!depts.isEmpty()){
            throw new DeptExistException("该部门已经存在");
        }

        Dept dept = new Dept();
        dept.setDeptName(name);
        dept.setRemark(remark);
        dept.setCreateDate(new Date());
        dept.setCreateStaffId(staff.getStaffId());
        // 默认新增的部门为有效部门
        dept.setIsValid(StatusConstant.DEPT_IS_VALID_ENABLED);

        // 生成部门编号
        // 根据标志位查询当前序列号
        SequenceExample sequenceExample = new SequenceExample();
        sequenceExample.or()
                .andNameEqualTo(DictConstant.DEPT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(sequenceExample);
        if(sequences.isEmpty()){
            // 如果没有查询到对应的序列号
            // 则表示部门尚未生成过序列号
            // 创建一个初始数据
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.DEPT_NO_PREFIX);
            sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
            // 添加到序列号表中
            sequenceMapper.insertSelective(sequence);

            // 生成对应的部门编号
            dept.setDeptNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        } else{
            // 如果查询到对应的序列号
            // 则查询到的数据有且仅有一条
            Sequence sequence = sequences.get(0);
            // 判断当前序列号的值是否达到了最大值
            if(DictConstant.DEPT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())){
                // 如果达到了最大值,则下一个值为初始值
                sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
            } else{
                // 如果尚未达到最大值,则下一个值为原有值的基础+1,格式不变
                sequence.setValue(ParameterUtil.nextValue(sequence.getValue()));
            }
            // 执行修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);
            // 生成对应的部门编号
            dept.setDeptNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }

        // 添加一级部门信息
        deptMapper.insertSelective(dept);
    }

    @Override
    public void addSonDept(String fatherId, String name, String remark, Staff staff) throws RequestParameterErrorException, LoginDisabledException, DeptExistException {
        if(ParameterUtil.isNull(fatherId) || ParameterUtil.isNull(name) || ParameterUtil.isNull(remark)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        if(null == staff){
            throw new LoginDisabledException("登录失效,请重新登录");
        }
        // 部门名称不能重复
        DeptExample example = new DeptExample();
        example.or()
                .andDeptNameEqualTo(name);
        List<Dept> depts = deptMapper.selectByExample(example);
        if(!depts.isEmpty()){
            throw new DeptExistException("该部门已经存在");
        }

        Dept dept = new Dept();
        dept.setDeptName(name);
        dept.setRemark(remark);
        dept.setCreateDate(new Date());
        dept.setCreateStaffId(staff.getStaffId());
        // 默认新增的部门为有效部门
        dept.setIsValid(StatusConstant.DEPT_IS_VALID_ENABLED);
        dept.setFatherDeptId(Integer.parseInt(fatherId));

        // 生成部门编号
        // 根据标志位查询当前序列号
        SequenceExample sequenceExample = new SequenceExample();
        sequenceExample.or()
                .andNameEqualTo(DictConstant.DEPT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(sequenceExample);
        if(sequences.isEmpty()){
            // 如果没有查询到对应的序列号
            // 则表示部门尚未生成过序列号
            // 创建一个初始数据
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.DEPT_NO_PREFIX);
            sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
            // 添加到序列号表中
            sequenceMapper.insertSelective(sequence);

            // 生成对应的部门编号
            dept.setDeptNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        } else{
            // 如果查询到对应的序列号
            // 则查询到的数据有且仅有一条
            Sequence sequence = sequences.get(0);
            // 判断当前序列号的值是否达到了最大值
            if(DictConstant.DEPT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())){
                // 如果达到了最大值,则下一个值为初始值
                sequence.setValue(DictConstant.DEPT_NO_SEQUENCE_INIT_VALUE);
            } else{
                // 如果尚未达到最大值,则下一个值为原有值的基础+1,格式不变
                sequence.setValue(ParameterUtil.nextValue(sequence.getValue()));
            }
            // 执行修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);
            // 生成对应的部门编号
            dept.setDeptNo(DictConstant.DEPT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }

        // 添加子部门信息
        deptMapper.insertSelective(dept);
    }

    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public List<Dept> findAll() {
        List<Dept> depts = deptMapper.selectAll();
        return depts;
    }

    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public Dept findById(String id) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        Dept dept = deptMapper.selectByPrimaryKey(Integer.parseInt(id));
        return dept;
    }

    @Override
    public void modifyDept(String id, String name, String remark) throws RequestParameterErrorException, DeptExistException {
        if(ParameterUtil.isNull(id) || ParameterUtil.isNull(name) || ParameterUtil.isNull(remark)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        // 部门名称不能重复
        DeptExample example = new DeptExample();
        example.or()
                .andDeptIdNotEqualTo(Integer.parseInt(id))
                .andDeptNameEqualTo(name);
        List<Dept> depts = deptMapper.selectByExample(example);
        if(!depts.isEmpty()){
            throw new DeptExistException("该部门已经存在");
        }

        Dept dept = new Dept();
        dept.setDeptId(Integer.parseInt(id));
        dept.setDeptName(name);
        dept.setRemark(remark);

        // 执行修改操作
        deptMapper.updateByPrimaryKeySelective(dept);
    }

    @Override
    public void enableDept(String id) throws RequestParameterErrorException, DeptStatusErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        // 根据主键查询当前部门信息
        Dept dept = deptMapper.selectByPrimaryKey(Integer.parseInt(id));
        // 查询上级部门的信息
        Dept fatherDept = deptMapper.selectByPrimaryKey(dept.getFatherDeptId());
        // 当当前部门存在上级部门且上级部门状态为禁用时,无法启用
        if(fatherDept != null && StatusConstant.DEPT_IS_VALID_DISABLED.equals(fatherDept.getIsValid())){
            throw new DeptStatusErrorException("请先启用上级部门");
        }
        // 启用当前部门
        dept.setIsValid(StatusConstant.DEPT_IS_VALID_ENABLED);
        deptMapper.updateByPrimaryKeySelective(dept);
    }

    @Override
    public void disableDept(String id) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        // 查询当前部门信息
        Dept dept = deptMapper.selectByPrimaryKey(Integer.parseInt(id));
        // 禁用当前部门
        dept.setIsValid(StatusConstant.DEPT_IS_VALID_DISABLED);
        deptMapper.updateByPrimaryKeySelective(dept);

        // 查询当前部门下属的子部门
        DeptExample example = new DeptExample();
        example.or()
                .andFatherDeptIdEqualTo(dept.getDeptId());
        List<Dept> sonDepts = deptMapper.selectByExample(example);
        // 禁用子部门
        for(Dept sonDept : sonDepts){
            // 使用递归进行处理
            disableDept(sonDept.getDeptId().toString());
        }
    }
}
